/*******************************************************************************
 * Copyright (c) 2014, 2015 IBM Corp.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * and Eclipse Distribution License v1.0 which accompany this distribution.
 *
 * The Eclipse Public License is available at
 *    http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at
 *   http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *    Allan Stockdill-Mander - initial API and implementation and/or initial documentation
 *******************************************************************************/

#if !defined(MQTTLiteOS_H)
#define MQTTLiteOS_H


#include <sys/types.h>

#if !defined(SOCKET_ERROR)
	/** error in socket operation */
	#define SOCKET_ERROR -1
#endif

#define INVALID_SOCKET SOCKET_ERROR

#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>

#ifdef LITEOS
    #include <wm_sockets.h>
    #include <wm_osal.h>
#else
#ifdef LINUX
    #include <stdint.h>
    #include <pthread.h>
    #include <sys/select.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
#else
    #error "not support platform"
#endif

#endif

#define MQTT_TASK

typedef struct Thread
{
#ifdef LITEOS
	tls_os_task_t task;
#else
    pthread_t task;
#endif
} Thread;

int ThreadStart(Thread*, void (*fn)(void*), void* arg);

typedef struct Timer
{
	struct timeval end_time;
} Timer;

typedef struct Mutex
{
#ifdef LITEOS
	tls_os_mutex_t * mutex;
#else
    pthread_mutex_t mutex;
#endif
} Mutex;

void MutexInit(Mutex*);
int MutexLock(Mutex*);
int MutexUnlock(Mutex*);
void MutexUninit(Mutex *);

void TimerInit(Timer*);
char TimerIsExpired(Timer*);
void TimerCountdownMS(Timer*, unsigned int);
void TimerCountdown(Timer*, unsigned int);
int TimerLeftMS(Timer*);
int64_t TimerToMs(Timer *);
int64_t TimevalToMs(struct timeval *a);
int64_t now();

typedef struct Network
{
	int my_socket;
	int (*mqttread) (struct Network*, unsigned char*, int, int);
	int (*mqttwrite) (struct Network*, unsigned char*, int, int);
} Network;

int linux_read(Network*, unsigned char*, int, int);
int linux_write(Network*, unsigned char*, int, int);

void NetworkInit(Network*);
int NetworkConnect(Network*, char*, int);
void NetworkDisconnect(Network*);

int GetTimeOfday(struct timeval *tv, struct timezone *tz);

uint32_t getTimeInSeconds();

#define PRINTF(fmt, ...) do { \
   uint32_t time = getTimeInSeconds(); \
   printf("[MQ] <%d.%03d> %s : "fmt, (int)(time/1000), (int)(time%1000), __func__ , ##__VA_ARGS__); \
} while (0)

#endif
